<?php
class ClsNaanalConfigGen
{
    private static $arrToken=array();
    private static $count=0;
    public function __construct()
    {
        
    }
    public static function refresh()
    {
        $content=file_get_contents("config.php");
        $arrToken= token_get_all($content);
        self::$count=count($arrToken);
        self::$arrToken=$arrToken;
    }
    public static function loadConfig()
    {
        if(empty(self::$arrToken))
        {
           self::refresh(); 
        }
    }
    /**
     * update config variable in config.php
     * @param type $key
     * @param type $value
     */
    public static function updateVarConfig($key,$value)
    {
        
    }
    ///skip empty lines and spaces
    public static function skipSpaces($index)
    {
        for($i=$index+1;$i<self::$count;$i++)
        {
            if(is_array(self::$arrToken[$i]) && self::$arrToken[$i][0]==370)
            {
                continue;
            }
            else
            {
                return $i;
            }
        }
        return -1;
    }
    public static function getDefineInsersionIndex()
    {
        for($ind=0;$ind<self::$count;$ind++)
        {
            $token=self::$arrToken[$ind];
            if(is_array($token) && $token[0]==369)
            {
                return $ind;
            }
        }
        return -1;
    }
    public static function getDefineValueIndex($key)
    {
        if(($defineIndex=self::getDefineKeyIndex($key))!=-1)
        {
            $defineBracketIndex=self::skipSpaces($defineIndex);
            $definekeyIndex=self::skipSpaces($defineBracketIndex);
            $defineCommaIndex=self::skipSpaces($definekeyIndex);
            $defineValueIndex=self::skipSpaces($defineCommaIndex);
            return $defineValueIndex;
        }
        return -1;
    }
    public static function extractValue($index)
    {
        ///if value is programing keyword
        if(self::$arrToken[$index][0]==307)
        {
            if(self::$arrToken[$index][1]=="null")
            {
                return null;
            }
            else if(self::$arrToken[$index][1]=="true")
            {
                return true;
            }
            else if(self::$arrToken[$index][1]=="false")
            {
                return false;
            }
        }
        return self::$arrToken[$index][0];
    }
    public static function getVarIndex($var)
    {
        if(self::$count===0)
        {
            self::refresh();
        }
        for($ind=0;$ind<self::$count;$ind++)
        {
            $token=self::$arrToken[$ind];
            if(is_array($token) && $token[0]==T_VARIABLE && $token[1]=='$'.$var)
            {
                return $ind;
            }
        }
        return -1;
    }
    public static function getDefineKeyIndex($key)
    {
        if(self::$count===0)
        {
            self::refresh();
        }
        for($ind=0;$ind<self::$count;$ind++)
        {
            $token=self::$arrToken[$ind];
            if(is_array($token) && $token[1]=="define")
            {
                $defineInd=$ind;
                $ind=self::skipSpaces($ind);
                if(!is_array(self::$arrToken[$ind]) && self::$arrToken[$ind]=="(")
                {
                    $ind=self::skipSpaces($ind);
                    if(is_array(self::$arrToken[$ind]) && (self::$arrToken[$ind][1]=="\"{$key}\"" || self::$arrToken[$ind][1]=="'{$key}'"))
                    {
                        return $defineInd;
                    }
                }
            }
        }
        return -1;
    }
    public static function loadDefaultDefineConfig()
    {
        self::loadConfig();
        $arrNewConfigToken = array();
        if(!self::$arrToken)
        {
            self::$arrToken[0]=array
            (
                367,'<?php
'
            );
            self::$arrToken[1]=array
            (
                365,'/*
 * Naanal ATS
 * Configuration File
 *
 * Copyright (C) 2013 - 2014 Unicomtech.
 *
 *
 * The contents of this file are subject to the MOZILA Public License
 * Version 1.1a (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.naanal.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is "Naanal ATS Standard Edition".
 *
 * The Initial Developer of the Original Code is Unicomtech.
 * Portions created by the Initial Developer are Copyright (C) 2013 - 2014
 * (or from the year in which this file was created to the year 2013) by
 * Unicomtech. All Rights Reserved.
 *
 *
 * 
 */
 '
            );
            self::$arrToken[2]=array
            (
                369,'?>'
            );
        }
        self::$count=count(self::$arrToken);
        foreach(ClsConfig::$CONFIG_VAR as $configVar=>$arrInfo)
        {
            if(is_string($arrInfo["data"]))
            {
                self::updateDefineConfig($configVar,"'{$arrInfo["data"]}'");
            }
            else
            {
                self::updateDefineConfig($configVar,$arrInfo["data"]);
            }
            self::$count=count(self::$arrToken);
        }
    }
    /**
     * update defined constant in config.php
     * @param type $key
     * @param type $value
     * @return boolean
     */
    public static function updateDefineConfig($key,$value)
    {
        /*if (!is_readable('config.php') || !is_writeable('config.php'))
        {
            die("config.php is not readable");
        }*/
        //$configContent = file_get_contents("config.php");
        //self::$arrToken =  token_get_all($configContent);
        $arrNewConfigToken = array();
        $defineIndex=self::getDefineKeyIndex($key);
        ///if key not exist
        $arrRenderConfigToken=array();
        if($defineIndex==-1)
        {
            $arrNewConfigToken[]=array
            (
                307,'define'
            );
            $arrNewConfigToken[]="(";
            $arrNewConfigToken[]=array
            (
                315,"'{$key}'"
            );
            $arrNewConfigToken[]=",";
            $arrNewConfigToken[]=array
            (
                315,$value
            );
            $arrNewConfigToken[]=")";
            $arrNewConfigToken[]=";
";
            
            $insersionIndex=self::getDefineInsersionIndex();
            for($i=0;$i<$insersionIndex;$i++)
            {
                $arrRenderConfigToken[]=self::$arrToken[$i];
            }
            for($j=0;$j<count($arrNewConfigToken);$j++)
            {
                $arrRenderConfigToken[]=$arrNewConfigToken[$j];
            }
            for($i=$insersionIndex;$i<count(self::$arrToken);$i++)
            {
                $arrRenderConfigToken[]=self::$arrToken[$i];
            }
            self::$arrToken=$arrRenderConfigToken;
        }
        else
        {
            $defineBracketIndex=self::skipSpaces($defineIndex);
            $definekeyIndex=self::skipSpaces($defineBracketIndex);
            $defineCommaIndex=self::skipSpaces($definekeyIndex);
            $defineValueIndex=self::skipSpaces($defineCommaIndex);
            self::$arrToken[$defineValueIndex][1]=$value;
        }
        self::$count=count(self::$arrToken);
        return true;
    }
    
    public static function render()
    {
        $newContent="";
        foreach(self::$arrToken as $token)
        {
            if(is_array($token))
            {
                if(is_null($token[1]))
                {
                    $newContent=$newContent."null";
                }
                else if($token[1]===false)
                {
                    $newContent=$newContent."false";
                }
                else if($token[1]===true)
                {
                    $newContent=$newContent."true";
                }
                else
                {
                    $newContent=$newContent.$token[1];
                }
            }
            else
            {
                $newContent=$newContent.$token;
            }
        }
        $result = file_put_contents(
            'config.php', $newContent . "\n"
        );
        self::refresh();
        if (!$result)
        {
            die("unable to update config values");
        }
    }
}
?>